fn main() {


    /*

    当将值从一个位置传递到另一个位置时候，都会重新评估所有权
    1. immutahble borrow 使用不可变借用，值的所有权仍然归发送者所有,接收者直接接受对该值的引用，而不是该值的副本，但是
        不能通过引用修改指向的值，编译器不允许这么做，释放资源的责任仍然由发送者承担，仅当发件人本身超过范围时，才会删除该值
    
    2. mutable borrow 使用可变的借用所有权和删除值的责任也由发送者承担，但是接收方能过够通过他们的接受引用来修改值

    3. move 所有权从一个地点转移到另一个地点，borrow关于释放该值的决定由该值的接送者通知，由于所有权发已从发送方转移
        到了接收方，因此发送方在讲引用移动到另一个上下文后不能再使用该引用，发送方在移动后对value的任何使用都会导致错误



    Self: 是当前对象的类型
    self: 方法的第一个参数名

    self是self:Self的简写,即self是当前类型的对象,会发生所有权转移
    &self是self:&Self的简写,即self是当前类型的引用,不会发生所有权转移
    &mut self是 self:&mut Self的简写,即self是当前类型的可变引用,不会发生所有权转移

    */



    let mut c1 = Counter::new(0);
    // ==========================  c1拥有所有权 ==========================
    println!("{}",c1.get_number());
    println!("{}",c1.get_number());
    c1.add(2);
    println!("{}",c1.get_number());
    println!("{}",c1.get_number());

    // ==========================  c1丧失所有权 ==========================
    // c1.give_up();
    // `c1` moved due to this method call
    // println!("{}",c1.get_number()); 

    /*
        main.rs(41, 9): move occurs because `c2` has type `Counter`, which does not implement the `Copy` trait
    */
    let c2 = Counter::new(1);
    let c3 = Counter::new(2);
    let c4 = Counter::combine(c2, c3);
    c2.get_number();
    c3.get_number();

    println!("Hello, ownership和结构体!");
}


struct Counter {
    number:i32,
}

impl Counter {
    // Self表示接结构体
    fn new(number: i32) -> Self {
        Self {
            number
        }
    }

    // 不可变借用
    fn get_number<'a>(&'a self)-> i32 {
        self.number
    }

    // 可变借用
    fn add<'a>(&'a mut self, increment:i32){
        self.number += increment;
    }

    // move用法1
    fn give_up(self){
        println!("free {}",self.number);
    }

    // move用法2
    fn combine(c1: Self, c2:Self) -> Self{

        Self {
            number: c1.number + c2.number
        }

    }

}